﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
using XYS.Core.Models;
using XYS.Core.Util;

namespace XYS.Core.Api.Middlewares
{
    /// <summary>
    /// 异常统一处理方案
    /// 异常处理 中间件
    /// </summary>
    public class ExceptionHandlerMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger logger;

        /// <summary>
        /// 统一异常处理方案
        /// 异常处理 中间件
        /// </summary>
        /// <param name="next"></param>
        /// <param name="loggerFactory"></param>
        public ExceptionHandlerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
        {
            _next = next;
            this.logger = loggerFactory.CreateLogger<ExceptionHandlerMiddleware>();
        }

        /// <summary>
        /// Invoke
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next.Invoke(context);
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(context, ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="exception"></param>
        /// <returns></returns>
        private async Task HandleExceptionAsync(HttpContext context, Exception exception)
        {
            logger.LogError(exception, exception.Message);
            if (GlobalCoreSetting.FormatRequestsIgnore.Any(x => Regex.IsMatch(context.Request.Path.Value, "^" + Regex.Escape(x).Replace("\\*", ".*") + "$"))) return;

            //返回结果
            var response = context.Response;
            response.StatusCode = (int)EnumStatusCode.OK;
            response.ContentType = "application/json";

            if (exception is ExistCheckExpression existCheckExpression)
            {
                //返回错误异常信息
                await response.WriteAsync(ResultModel.Failed(existCheckExpression.StatusCode, exception.Message).ToJson());
                return;
            }
            await response.WriteAsync(ResultModel.Failed(EnumStatusCode.InternalServerError, "系统繁忙").ToJson());
        }

    }
}
